package com.andox.fn.inf.rpc.rest.serializer;

import org.apache.commons.codec.binary.Base64;

import com.andox.fn.inf.rpc.rest.common.Constants;
import com.andox.fn.inf.rpc.rest.extension.Extension;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;


/**
 * @ClassName: KryoSerializer
 * @author: Andox
 * @date: 2019年8月1日 上午9:37:25
 */
@Extension("kryo")
public class KryoSerializer implements Serializer {
	private static final ThreadLocal<Kryo> kryo = new ThreadLocal<Kryo>() {
		protected Kryo initialValue() {
			return new Kryo();
		};
	};

	@Override
	public byte[] serialize(Object object) {
		Output output = new Output(2048, Constants.DEFAULT_MAX_SERIALIZER_BUFFER_SIZE);
		kryo.get().writeClassAndObject(output, object);
		byte[] result = output.toBytes();
		output.close();
		return result;
	}

	@Override
	public String serializeAsString(Object object) {
		return Base64.encodeBase64String(this.serialize(object));
	}

	public static void main(String[] args) {
		KryoSerializer k = new KryoSerializer();
		System.out.println(k.serializeAsString("def"));
	}
	@SuppressWarnings("unchecked")
	@Override
	public <T> T unserialize(byte[] source, Class<T> clazz) {
		Input input = new Input(source);
		T object = (T)kryo.get().readClassAndObject(input);
		input.close();
		return object;
	}

	@Override
	public <T> T unserializeFromString(String source, Class<T> clazz) {
		return this.unserialize(Base64.decodeBase64(source), clazz);
	}
}
